package com.shangyueshang.utils;

import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * @author: JokeyZheng
 * @email: zhengjingfeng@ruqimobility.com
 * @created: 2022/8/31 22:09
 * @version: v1.0.0
 */
public class IPUtil {

    public static final String UNKNOWN = "unknown";

    public static final String X_FORWARDED_FOR = "x-forwarded-for";

    public static final String PROXY_CLIENT_IP = "Proxy-Client-IP";

    public static final String WL_PROXY_CLIENT_IP = "WL-Proxy-Client-IP";

    public static final String HTTP_CLIENT_IP = "HTTP_CLIENT_IP";

    public static final String HTTP_X_FORWARDED_FOR = "HTTP_X_FORWARDED_FOR";

    public static final String X_REAL_IP = "X-Real-IP";

    public static final String COMMA = ",";

    /**
     * string ip to long
     */
    public static long ipStrToLong(String ipaddress) {
        long[] ip = new long[4];
        int i = 0;
        for (String ipStr : ipaddress.split("\\.")) {
            ip[i] = Long.parseLong(ipStr);
            i++;
        }
        return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3];
    }

    /**
     * ip long to String
     */
    public static String iplongToIp(long ipaddress) {
        StringBuffer sb = new StringBuffer("");
        sb.append(String.valueOf((ipaddress >>> 24)));
        sb.append(".");
        sb.append(String.valueOf((ipaddress & 0x00FFFFFF) >>> 16));
        sb.append(".");
        sb.append(String.valueOf((ipaddress & 0x0000FFFF) >>> 8));
        sb.append(".");
        sb.append(String.valueOf((ipaddress & 0x000000FF)));
        return sb.toString();
    }


    private static final String LOCAL_HOST = "127.0.0.1";

    private static final String INVALID_IP = "0:0:0:0:0:0:0:1";

    /**
     * 获取用户真实IP地址
     *
     * @param request
     * @return
     */
    public static String getIpAddress(HttpServletRequest request) {
        // Nginx的反向代理标志
        String ip = request.getHeader(X_FORWARDED_FOR);
        if (!isValid(ip)) {
            // Apache的反向代理标志
            ip = request.getHeader(PROXY_CLIENT_IP);
        }
        if (!isValid(ip)) {
            // WebLogic的反向代理标志
            ip = request.getHeader(WL_PROXY_CLIENT_IP);
        }
        if (!isValid(ip)) {
            // 较少出现
            ip = request.getHeader(HTTP_CLIENT_IP);
        }
        if (!isValid(ip)) {
            ip = request.getHeader(HTTP_X_FORWARDED_FOR);
        }
        if (!isValid(ip)) {
            ip = request.getHeader(X_REAL_IP);
        }
        if (!isValid(ip)) {
            ip = request.getRemoteAddr();
            if (LOCAL_HOST.equals(ip) || INVALID_IP.equals(ip)) {
                // 根据网卡取本机配置的IP
                InetAddress inetAddress = null;
                try {
                    inetAddress = InetAddress.getLocalHost();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
                ip = inetAddress.getHostAddress();
            }
        }

        // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        if (ip != null && ip.indexOf(COMMA) > 0) {
            ip = ip.substring(0, ip.indexOf(COMMA));
        }
        return ip;
    }

    private static boolean isValid(String ip) {
        return !(ObjectUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip));
    }
}
